<?php

/**
 * PSK
 *
 * An open source PHP web application development framework.
 *
 * @package       PSK (PHP Sınıf Kütüphanesi)
 * @author        Namık Kemal Karasu
 * @copyright     Copyright (C) Namık Kemal Karasu
 * @license       GPLv3
 * @since         Version 0.
 * @link          http://nkkarasu.net/psk/
 * @link          http://code.google.com/p/phpsk/
 */

/**
 * PSK_Layout class.
 *
 * The object wich is responsible layouts of pages.
 *
 * @package        PSK
 * @subpackage     Libraries
 * @category       Layout
 * @author         Namık Kemal Karasu
 * @link           TODO add PSK_Layout class documentation link.
 *
 * @note           Edited for HTML5.
 */

class PSK_Layout extends PSK_Object
{
	const js =
		'
<div>
  <input type="hidden" name="_source" id="_source" value="" />
  <input type="hidden" name="_target" id="_target" value="" />
  <input type="hidden" name="_method" id="_method" value="" />
  <input type="hidden" name="_args" id="_args" value="" />
  <!-- <script type="text/javascript"> -->
  <script>
    var _form = document.forms["%1$s"];
    if (!_form) {
        _form = document.%1$s;
    }

    function _postBack(par_Target, par_Method, par_Args) {
      if (!_form.onsubmit || (_form.onsubmit() != false)) {
        _form._source.value = "psk_control";
        _form._target.value = par_Target;
        _form._method.value = par_Method;
        _form._args.value = par_Args;
        _form.submit();
      }
    }
  </script>
</div>
';

	/**
	 * Singleton instance.
	 *
	 * @var PSK_Layout
	 */
	protected static $__instance = null;

	/**
	 * Document type of the genareted pages.
	 *
	 * @var string
	 */
	private $_docType = '<!doctype html>';
	//private $_docType = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
	//Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional
    //.dtd">';

	/**
	 * XMLNS of the generated files.
	 *
	 * @var string
	 */
	private $_xmlns = 'http://www.w3.org/1999/xhtml';

	private $_language = 'tr';

	/**
	 * Character set of the generated pages.
	 *
	 * @var string
	 */
	private $_charSet = 'utf-8';

	/**
	 * Defines the TITLE of the generated HTML.
	 *
	 * @var string
	 */
	private $_title = '';

	/**
	 * This property's value is inserted into HEAD section of the geretad HTML.
	 *
	 * @var string
	 */
	private $_customHead = '';

	/**
	 * This property's value is inserted as the CLASS property of the BODY tag
	 * of the generated HTML.
	 *
	 * @var string
	 */
	private $_bodyClass = '';

	/**
	 * This property's value is inserted after the BODY tag of the
	 * generated HTML.
	 *
	 * @var string
	 */
	private $_bodyHeader = '';

	/**
	 * This property's value is inserted before the end of BODY tag of the
	 * generated HTML.
	 *
	 * @var string
	 */
	private $_bodyFooter = '';

	/**
	 * This array contains the path and the file names of the external script
	 * files.
	 *
	 * @var array
	 */
	private $_scripts = array();

	/**
	 * This array contains the path and the file names of the external style
	 * sheet (css) files.
	 *
	 * @var array
	 */
	private $_styles = array();

	/**
	 * This array contains the meta information of the generated pages.
	 *
	 * @var array
	 */
	private $_metas = array();

	/**
	 * This array contains the properties of the HTML FORM of the genrated
	 * pages.
	 *
	 * @var array
	 */
	private $_formParams = array();

	/**
	 * The template file for the layout. Includes full path and file name.
	 *
	 * @var string
	 */
	private $_template = '';

	/**
	 * The template name of the layout. This is not a file name or path.
	 *
	 * @var string
	 */
	private $_templateName = '';

	/**
	 * Constructor of PSK_Layout.
	 *
	 * @param string $par_Name A name for the object.
	 */
	function  __construct($par_Name = '')
	{
		parent::__construct($par_Name);
	}

	/**
	 * Returns singleton instance of PSK_Layout.
	 *
	 * @return PSK_Layout
	 */
	public static function getInstance()
	{
		if (null === self::$__instance) {
			self::$__instance = new self();
		}
		return self::$__instance;
	}

	/**
	 * Renders the head section of the pages.
	 */
	function RenderHead()
	{
		echo "<!-- LAYOUT PRINTING -->\n";
		echo "$this->_docType\n";
		$xmlns = $this->_xmlns == '' ? '' : ' xmlns="' . $this->_xmlns . '"';
		$lang = $this->_language == '' ? '' : ' lang="'.$this->_language.'"';
		echo "<html$xmlns$lang>\n";
		echo "<head>\n";
		//echo '<meta http-equiv="Content-Type" content="text/html; charset=' .
		//	$this->_charSet . "\" />\n";
		echo '<meta charset="'.$this->_charSet."\"/>\n";
		foreach ($this->_metas as $name => $content) {
			echo '<meta name="' . $name . '" content="' . $content . '" />' . "\n";
		}
		echo "<title>" . $this->_title . "</title>\n";
		foreach ($this->_styles as $style) {
			//echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" .
			//	PSK_Uri::getInstance()->IncludePath($style) . "\" />\n";
			echo "<link rel=\"stylesheet\" href=\"" .
				PSK_Uri::getInstance()->IncludePath($style) . "\" />\n";
		}
		foreach ($this->_scripts as $script) {
			echo "<script type=\"text/javascript\" src=\"" .
				PSK_Uri::getInstance()->IncludePath($script) . "\"></script>\n";
		}

		//PSK_Log::getInstance()->WriteArray($this->_scripts);

		echo $this->_customHead;
		echo "\n</head>\n";
	}

	/**
	 * Renders the header part of the pages.
	 */
	function RenderHeader()
	{
		$fp = " ";
		foreach ($this->_formParams as $name => $value) {
			$fp .= $name . "=\"" . $value . "\" ";
		}

		$c = $this->_bodyClass == "" ? "" : " class=\"" . $this->_bodyClass . "\" ";

		echo "<body" . $c . ">\n<form action=\"\" method=\"post\" name=\"" .
			$this->__objectName . "\" id=\"" . $this->__objectName . "\"" . $fp . ">";
		echo sprintf(self::js, $this->__objectName);
		echo $this->_bodyHeader;
	}

	/**
	 * Renders the footer part of the pages.
	 */
	function RenderFooter()
	{
		echo $this->_bodyFooter;
		echo "\n</form>\n</body>\n</html>";
	}

	/**
	 * Adds a new script file link to Scripts array.
	 *
	 * @param string $par_Script Path and file name of the script file.
	 */
	function AddScriptLink($par_Script)
	{
		$this->_scripts[] = $par_Script;
	}

	/**
	 * Adds a new style file link to Styles array.
	 *
	 * @param string $par_Style
	 */
	function AddStyleLink($par_Style)
	{
		$this->_styles[] = $par_Style;
	}

	/**
	 * Adds meta information to generated page.
	 *
	 * @param string $par_Name
	 * @param string $par_Content
	 */
	function AddMeta($par_Name, $par_Content)
	{
		$this->_metas[$par_Name] = $par_Content;
	}

	/**
	 * Adds form properties.
	 *
	 * @param string $par_Name
	 * @param string $par_Value
	 */
	function AddFormParam($par_Name, $par_Value)
	{
		$this->_formParams[$par_Name] = $par_Value;
	}

	/**
	 * Expands the title of the page with given values.
	 *
	 * @param string $par_TitleEx
	 */
	function AppendTitle($par_TitleEx)
	{
		$this->_title .= $par_TitleEx;
	}

	/**
	 * Expands the custom head with given values.
	 *
	 * @param string $par_CustomHead
	 */
	function AppendCustomHead($par_CustomHead)
	{
		$this->_customHead .= $par_CustomHead;
	}

	/**
	 * Sets the document type of the generated pages.
	 *
	 * @param string $par_DocType
	 */
	public function setDocType($par_DocType)
	{
		$this->_docType = $par_DocType;
	}

	/**
	 * Sets the xmlns of the generated pages.
	 *
	 * @param string $par_Xmlns
	 */
	public function setXmlns($par_Xmlns)
	{
		$this->_xmlns = $par_Xmlns;
	}

	/**
	 * Sets the character set of the generated pages.
	 *
	 * @param string $par_CharSet
	 */
	public function setCharSet($par_CharSet)
	{
		$this->_charSet = $par_CharSet;
	}

	/**
	 * Sets the title of the generated pages.
	 *
	 * @param string $par_title
	 */
	public function setTitle($par_title)
	{
		$this->_title = $par_title;
	}

	/**
	 * Sets the value of the CustomHead property.
	 *
	 * @param string $par_CustomHead
	 */
	public function setCustomHead($par_CustomHead)
	{
		$this->_customHead = $par_CustomHead;
		//PSK_Log::getInstance()->WriteDebug($par_CustomHead);
	}

	/**
	 * Sets the value of the BodyClass property. This property's value is
	 * inserted as the CLASS property of the BODY tag of the generated HTML.
	 *
	 * @param string $par_BodyClass
	 */
	public function setBodyClass($par_BodyClass)
	{
		$this->_bodyClass = $par_BodyClass;
	}

	/**
	 * Sets the value of the BodyHeader property. This property's value is
	 * inserted before the start of BODY tag of the generated HTML.
	 *
	 * @param string $par_BodyHeader
	 */
	public function setBodyHeader($par_BodyHeader)
	{
		$this->_bodyHeader = $par_BodyHeader;
	}

	/**
	 * Sets the value of the BodyFooter property. This property's value is
	 * inserted before the end of BODY tag of the generated HTML.
	 *
	 * @param string $par_BodyFooter
	 */
	public function setBodyFooter($par_BodyFooter)
	{
		$this->_bodyFooter = $par_BodyFooter;
	}

	/**
	 * Sets the value of the Scripts property. Scripts is an array that contains
	 * the path and the file names of the external script files.
	 *
	 * @param array $par_Scripts
	 */
	public function setScripts(array $par_Scripts)
	{
		$this->_scripts = $par_Scripts;
	}

	/**
	 * Sets the value of the Styles property. Styles is an array that contains
	 * the path and the file names of the style sheet (css) files.
	 *
	 * @param array $par_Styles Array which contains style file names and paths.
	 */
	function setStyles(array $par_Styles)
	{
		$this->_styles = $par_Styles;
	}

	/**
	 * Adds extra style info to styles array. Use this for inherited layouts
	 * to add new styles to existing ones. If you do not want use styles from
	 * base layout then use setStyles method.
	 *
	 * @param array $par_Styles Array which contains style file names and paths.
	 */
	function setExtraStyles(array $par_Styles)
	{
		foreach ($par_Styles as $style) {
			$this->_styles[] = $style;
		}
	}

	/**
	 * Sets the value of the Metas property. This array contains the meta
	 * information of the generated pages.
	 *
	 * @param array $par_Meta
	 */
	function setMetas(array $par_Meta)
	{
		foreach ($par_Meta as $name => $content) {
			$this->_metas[$name] = $content;
		}
	}

	/**
	 * Sets the FormParams property.
	 *
	 * @param array $par_FormParams
	 */
	function setFormParams(array $par_FormParams)
	{
		foreach ($par_FormParams as $name => $value) {
			$this->_formParams[$name] = $value;
		}
	}

	/**
	 * Sets the template file propery.
	 *
	 * @param string $par_Template
	 */
	function setTemplate($par_Template)
	{
		if (trim($par_Template) == '') return;
		$tf = PSK_Application::getInstance()->getFullTemplatePath() .
			$par_Template . '.phtml';
		if (is_file($tf)) {
			$this->_template = $tf;
			$this->_templateName = $par_Template;
		} else {
			throw new Exception(PSK_STR_LYT_INVALIDTEMPLATEFILE . ' : ' . $tf);
		}
	}

	/**
	 * Returns the path and file name of the template.
	 *
	 * @return string.
	 */
	function getTemplate()
	{
		return $this->_template;
	}

	/**
	 * Returns the template name. This is not a path or file name.
	 *
	 * @return string Name of the template
	 */
	function getTemplateName()
	{
		return $this->_templateName;
	}
}
